package com.itheima.service.mongo;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.domain.mongo.*;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;


    //发布动态
    @Override
    public void saveMovement(Movement movement) {

        //向动态表上传信息，返回动态id
        //设置动态大数据用的pid
        movement.setPid(idService.getNextId(ConstantUtil.MOVEMENT_ID));
        mongoTemplate.save(movement);
        ObjectId movementId = movement.getId();

        //向自己的动态表中上传信息
        MyMovement myMovement = new MyMovement();
        myMovement.setCreated(System.currentTimeMillis());
        myMovement.setPublishId(movementId);
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());

        //查询自己的朋友
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //遍历集合，添加动态id和userId
        for (Friend friend : friendList) {
            Long friendId = friend.getFriendId();

            //赋值
            FriendMovement friendMovement = new FriendMovement();
            friendMovement.setUserId(movement.getUserId());
            friendMovement.setPublishId(movementId);
            friendMovement.setCreated(System.currentTimeMillis());

            mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);

        }

    }

    //查看自己发布的动态
    @Override
    public PageBeanVo findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//排序
                .skip((pageNum - 1) * pageSize).limit(pageSize);//分页

        List<Movement> movementList = new ArrayList<>();
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                ObjectId publishId = myMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //统计数量
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }



    //查询我的好友的动态
    @Override
    public PageBeanVo findMyFriendMovement(Long userId,Integer pageNum, Integer pageSize) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize);

        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //2. 将得到的动态id遍历
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovementList)) {
            for (FriendMovement friendMovement : friendMovementList) {
                ObjectId publishId = friendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计记录数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //5. 封装返回结果
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }



    //查看推荐动态
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {

        //查询条件
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("score")))
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize);

        //根据userId查询推荐表中的publishId
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        //创建一个集合储存动态信息
        ArrayList<Movement> movementList = new ArrayList<>();

        //判断recommendMovementList是否为空
        if (CollectionUtil.isNotEmpty(recommendMovementList)) {
            for (RecommendMovement recommendMovement : recommendMovementList) {
                //取出publishId
                ObjectId publishId = recommendMovement.getPublishId();

                //在movement表中查找对应的动态信息
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //查询出数据条数
        long count = mongoTemplate.count(query, RecommendMovement.class);

        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }


    //查询指定id的动态详情
    @Override
    public Movement findMovementById(String movementId) {
        return mongoTemplate.findById(new ObjectId(movementId),Movement.class);
    }


    //查询动态评论
    @Override
    public PageBeanVo findMovementComment(String movementId, Integer pageNum, Integer pageSize) {
        Query query = new Query(Criteria.where("publishId")
                .is(new ObjectId(movementId))
                .and("commentType").is(2)
        )
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize);

        List<Comment> commentList = mongoTemplate.find(query, Comment.class);

        //统计评论数
        long count = mongoTemplate.count(query, Comment.class);

        return new PageBeanVo(pageNum,pageSize,count,commentList);
    }


    //查询动态
    @Override
    public PageBeanVo findMovementByUid(Long uid, Integer stateInt, Integer pageNum, Integer pageSize) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize)
                .limit(pageSize);

        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }

        if (stateInt != null) {
            query.addCriteria(Criteria.where("state").is(stateInt));
        }

        //查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //统计
        long count = mongoTemplate.count(query, Movement.class);

        //返回vo
        return new PageBeanVo(pageNum, pageSize, count, movementList);

    }



    @Override
    public void updateMovementState(Movement movement) {
        mongoTemplate.save(movement);
    }

    //消息通过
    @Override
    public void messagesPass(String[] str) {


        //设置where部分
        Query query = new Query(
                //条件
                Criteria.where("id").in(str)
        );

        //设置set部分
        Update update = new Update();
        update.set("state", 1);

        //更新多个
        mongoTemplate.updateMulti(query, update, Movement.class);
    }

    //消息拒绝
    @Override
    public void messagesReject(String[] str) {

        //设置where部分
        Query query = new Query(
                //条件
                Criteria.where("id").in(str)
        );

        //设置set部分
        Update update = new Update();
        update.set("state", 2);

        //更新多个
        mongoTemplate.updateMulti(query, update, Movement.class);

    }
}
